package com.winter.main.filter;

import com.alibaba.fastjson.JSON;
import com.winter.main.constant.SystemConstant;
import com.winter.main.model.dto.BjuiDto;
import com.winter.main.model.entity.SysUser;
import com.winter.main.service.RedisService;
import com.winter.main.utils.ShiroFilterUtil;
import org.apache.catalina.Session;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * Desc: 访问拦截1
 * Author: dushuang
 * Date: Create in 2018/5/13
 */
public class MainFilter extends AccessControlFilter {

    private Logger logger = LogManager.getLogger(this);

    private SessionManager sessionManager;

    private SecurityManager securityManager;

    @Autowired
    private RedisService redisService;

    public SessionManager getSessionManager() {
        return sessionManager;
    }

    public SecurityManager getSecurityManager() {
        return securityManager;
    }

    public void setSecurityManager(SecurityManager securityManager){
        this.securityManager = securityManager;
    }

    public void setSessionManager(SessionManager sessionManager){
        this.sessionManager = sessionManager;
    }

    @Override
    protected boolean preHandle(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        Subject subject = getSubject(servletRequest, servletResponse);
        HttpServletRequest request = (HttpServletRequest) servletRequest;
//        if(subject == null || !subject.isAuthenticated()){
//            // 没有登录
//            return false;
//        }
        HttpSession session = request.getSession();
        if(session.getAttribute(SystemConstant.SESSION_USER) == null){
            // 没有session
            if(ShiroFilterUtil.isAjax(request)){
                BjuiDto bjuiDto = new BjuiDto();
                logger.info("当前没有session");
                bjuiDto.setStatusCode("301");
                bjuiDto.setMessage("当前用户已退出，请重新登录。");
                servletResponse.setContentType("application/json;charset=utf-8");
                servletResponse.getWriter().write(JSON.toJSONString(bjuiDto));
            }else{
                WebUtils.issueRedirect(servletRequest, servletResponse , "/system/user/login");
            }
            return false;
        }
        SysUser user = (SysUser)session.getAttribute(SystemConstant.SESSION_USER);
        String sessionId = session.getId().toString();
        //logger.info("当前用户sessionId为: "+ sessionId);
        // 如果sessionId与redis存的不一致,则删除之前的session
        if(redisService.exists("session_user:key:"+ user.getId())){
            String activeSessionId = redisService.get("session_user:key:"+ user.getId()).toString();
            //logger.info("当前活动的sessionId: "+ activeSessionId);
            // 判断是否一致
            if(!sessionId.equals(activeSessionId)){
                //logger.info("session不一致,判断为踢出用户!...");
                logger.info("(mainFilter)当前用户已在其他地方登陆...");
                subject.logout();
                BjuiDto bjuiDto = new BjuiDto();
                if(ShiroFilterUtil.isAjax(servletRequest)){
                    // 判断如果为Ajax请求
                    logger.info("请求方式为Ajax!");
                    bjuiDto.setStatusCode("301");
                    bjuiDto.setMessage("当前用户已在其他地方登陆，请重新登录。");
                    servletResponse.setContentType("text/html;charset=utf-8");
                    servletResponse.getWriter().write(JSON.toJSONString(bjuiDto));
                } else {
                    WebUtils.issueRedirect(servletRequest, servletResponse , "/system/user/login");
                }
                return false;
            }
        }
        return true;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        return true;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        return false;
    }
}
